package com.hsy.crm.web.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hsy.crm.web.domain.cm.App;
import com.hsy.crm.web.domain.cm.PageResult;
import com.hsy.crm.web.domain.cm.Unified;
import com.hsy.crm.web.domain.entity.Dict;
import com.hsy.crm.web.domain.entity.StoreCheck;
import com.hsy.crm.web.domain.entity.StoreCheckDetail;
import com.hsy.crm.web.domain.entity.StoreProduct;
import com.hsy.crm.web.domain.ex.ServiceException;
import com.hsy.crm.web.domain.po.storeCheck.StoneCheckPagePo;
import com.hsy.crm.web.domain.po.storeCheck.StoneCheckStonePagePo;
import com.hsy.crm.web.domain.vo.storeCheck.StoneCheckPageVo;
import com.hsy.crm.web.domain.vo.storeCheck.StoneCheckStonePageVo;
import com.hsy.crm.web.domain.vo.storeCheck.StoneCheckVo;
import com.hsy.crm.web.mapper.StoreCheckDetailMapper;
import com.hsy.crm.web.mapper.StoreCheckMapper;
import com.hsy.crm.web.mapper.StoreProductMapper;
import com.hsy.crm.web.service.base.BaseService;
import com.hsy.crm.web.service.base.CacheService;
import com.hsy.crm.web.service.base.DataInitService;
import com.hsy.crm.web.utils.ServiceUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class StoreCheckService extends BaseService<StoreCheck> {

    @Autowired
    StoreCheckMapper storeCheckMapper;

    @Autowired
    DictService dictService;

    @Autowired
    StoreCheckDetailMapper storeCheckDetailMapper;

    @Autowired
    StoreProductMapper storeProductMapper;

    @Transactional
    public Unified<StoreCheck> start(StoreCheck storeCheck) {
        //插入一条主记录
        storeCheck.setCode(DataInitService.getOrderCode());
        storeCheck.setStatus(App.Status.BC);
        ServiceUtils.init_entity_insert(storeCheck);
        storeCheckMapper.insert(storeCheck);

        //盘存锁 1盘存中    0(已盘存|未开始)
        return checkStone(storeCheck,App.StoneCheck.END,App.StoneCheck.ING);
    }

    @Transactional
    public Unified<StoreCheck> end(StoreCheck storeCheck) {

        //盘存库存更新到正式库存
        StoreCheckDetail detail = new StoreCheckDetail();
        detail.setCustomerId(storeCheck.getCustomerId());
        Long stoneCheckId = getCheckingId(storeCheck);

        if(stoneCheckId==-1L){
            throw new ServiceException("Store check status error");
        }



        detail.setStoreCheckId(stoneCheckId);
        List<StoreCheckDetail> details = storeCheckDetailMapper.select(detail);
        for (StoreCheckDetail checkDetail : details){
            Long storeProductId = getStoreProductId(checkDetail,storeCheck.getCustomerId());

            checkDetail.setStoreProductId(storeProductId);
            checkDetail.setCustomerId(storeCheck.getCustomerId());
            storeCheckMapper.updateStoneProduct2(checkDetail);
        }

        StoreCheck updateCheck = new StoreCheck();
        updateCheck.setId(stoneCheckId);
        updateCheck.setStatus(App.Status.SH);
        updateCheck.setCustomerId(storeCheck.getCustomerId());
        storeCheckMapper.updateByPrimaryKeySelective(updateCheck);

        //盘存锁 1盘存中    0(已盘存|未开始)
        return checkStone(storeCheck,App.StoneCheck.ING,App.StoneCheck.END);
    }

    public Unified<Integer> getStoneCheckCurrStatus(StoreCheck storeCheck) {
        Unified<Integer> unified = new Unified<>();

        Dict dict = new Dict(App.Dict.STORE_CHECK_CODE, storeCheck.getCustomerId());
        dict = dictService.getByCode(dict);

        unified.setData(dict.getValue());

        return unified;
    }

    @Transactional
    public Unified<Integer> insert(StoneCheckVo stoneCheckVo) {
        Unified<Integer> unified = new Unified<>();

        String customerId = stoneCheckVo.getCustomerId();

        StoreCheck storeCheck = new StoreCheck();
        storeCheck.setCustomerId(stoneCheckVo.getCustomerId());
        Long stoneCheckId = getCheckingId(storeCheck);

        if(stoneCheckId==-1L){
            throw new ServiceException("Store check status error");
        }

        for (StoreCheckDetail detail : stoneCheckVo.getDetails()){

            if( !CacheService.hasProductId(customerId,detail.getProductId())){
                throw new ServiceException(detail.getProductId());
            }

            Long checkNumber = detail.getCheckNumber();
            detail.setCustomerId(customerId);
            detail.setStoreCheckId(stoneCheckId);
            detail.setCheckNumber(null);
            Long detailId = storeCheckMapper.getDetail(detail);
            if( detailId != null ){
                StoreCheckDetail updateDetail = new StoreCheckDetail();
                updateDetail.setId(detailId);
                updateDetail.setCheckNumber(checkNumber);
                updateDetail.setCheckPrice(detail.getCheckPrice());
                updateDetail.setCustomerId(stoneCheckVo.getCustomerId());
                storeCheckDetailMapper.updateByPrimaryKeySelective(updateDetail);
            }else{
                detail.setCheckNumber(checkNumber);
                ServiceUtils.init_entity_insert(detail);
                storeCheckDetailMapper.insert(detail);
            }
        }

        return unified;
    }

    public PageResult<StoneCheckPagePo> page(StoneCheckPageVo stoneCheckPageVo) {
        Page page = PageHelper.startPage(stoneCheckPageVo.getPage(),stoneCheckPageVo.getLimit());
        PageResult<StoneCheckPagePo> pageResult = new PageResult<>();
        pageResult.setRows(storeCheckMapper.page(stoneCheckPageVo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    public PageResult<StoneCheckStonePagePo> stonePage(StoneCheckStonePageVo stoneCheckStonePageVo) {
        Page page = PageHelper.startPage(stoneCheckStonePageVo.getPage(),stoneCheckStonePageVo.getLimit());
        PageResult<StoneCheckStonePagePo> pageResult = new PageResult<>();

        StoreCheck storeCheck = new StoreCheck();
        storeCheck.setCustomerId(stoneCheckStonePageVo.getCustomerId());
        Long stoneCheckId = getCheckingId(storeCheck);
        stoneCheckStonePageVo.setStoreCheckId(stoneCheckId);
        pageResult.setRows(storeCheckMapper.stonePage(stoneCheckStonePageVo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    public PageResult<StoneCheckStonePagePo> stoneHisPage(StoneCheckStonePageVo stoneCheckStonePageVo) {
        Page page = PageHelper.startPage(stoneCheckStonePageVo.getPage(),stoneCheckStonePageVo.getLimit());
        PageResult<StoneCheckStonePagePo> pageResult = new PageResult<>();
        pageResult.setRows(storeCheckMapper.stoneHisPage(stoneCheckStonePageVo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    private Long getStoreProductId(StoreCheckDetail checkDetail,String customerId){
        StoreProduct storeProduct = new StoreProduct();
        storeProduct.setUnitId(checkDetail.getUnitId());
        storeProduct.setStoreId(checkDetail.getStoreId());
        storeProduct.setProductId(checkDetail.getProductId());
        storeProduct.setCompanyId(checkDetail.getCompanyId());
        storeProduct.setCustomerId(customerId);
        return storeProductMapper.selectStoreProduct(storeProduct);
    }

    private Unified<StoreCheck> checkStone(StoreCheck storeCheck, int needStatus, int finalStatus) {
        Unified<StoreCheck> unified = new Unified<>();

        Dict dict = new Dict(App.Dict.STORE_CHECK_CODE, storeCheck.getCustomerId());
        dict = dictService.getByCode(dict);

        //盘存锁 1盘存中    0(已盘存|未开始)
        if( dict.getValue() == needStatus ){
            dict.setValue(finalStatus);
            dictService.update(dict);
        }else{
            throw new ServiceException("Store check status error");
        }
        unified.setData(storeCheck);
        return unified;
    }

    private Long getCheckingId(StoreCheck storeCheck){
        return storeCheckMapper.getCheckingId(storeCheck);
    }

}
